<?php declare(strict_types=1);

/**
 * @author      guosir
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Apis\Promotion\Ctl;

use Srv\Apps\Apis\Order\Ctl\PayCtl;
use Srv\Apps\Proto\DTO\Promotion\RechargeActAddDTO;
use Srv\Apps\Proto\DTO\Promotion\RechargeActEditDTO;
use Srv\Apps\Proto\DTO\Promotion\RechargeActListDTO;
use Srv\Apps\Proto\Enum\YesOrNoEnum;
use Srv\Apps\Proto\VO\Order\PayGoodsVO;
use Srv\Apps\Proto\VO\Promotion\RechargeActListVO;
use Srv\Apps\Proto\VO\Promotion\RechargeActVO;
use Srv\Libs\Common\CommArray;
use Srv\Libs\Common\CommTime;
use Srv\Libs\Frame\ControllerAbstract;
use Srv\Libs\Frame\Page;
use Srv\Libs\Storage\DataMysql;

final class RechargeActCtl extends ControllerAbstract
{
    private ?DataMysql $DbAuto              = null;     // DB-Write



    /**
     * @return static
     * tag
     */
    final public static function tag():self
    {
        $thisObject                         = self::tagGet();
        if($thisObject instanceof self){
            $thisObject->DbAuto             = self::getDbAuto();
        }
        return $thisObject;
    }

    /**
     * @param int $rpaId
     * @return array
     * getRechargeActSrc
     */
    public function getRechargeActSrc(int $rpaId):array
    {
        if($rpaId < 1) return [];
        $isFail     = false;
        $info       = $this->DbAuto->getDataOne('SELECT rpa_id, rpa_name, rpa_status, rpa_start_time, rpa_stop_time, rpa_time, pgsp_id_android, pgsp_id_apple, pgsp_id_web, rpa_create_time, rpa_update_time FROM '.$this->DbAuto->getTableNameAll('recharge_promotion_act').' WHERE rpa_id='.$rpaId.' AND rpa_delete=0', $isFail);
        if($isFail || !isset($info['rpa_id'])) return [];
        return $info;
    }

    /**
     * @param Page $Page
     * @param array $whereData
     * @return RechargeActListVO|null
     * getRechargeActList
     */
    public function getRechargeActList(Page $Page, array $whereData): ?RechargeActListVO
    {
        $limitString            = $Page->getLimitString();
        $whereString            = ' WHERE rpa_delete=0 ';
        // 检索条件
        if(count($whereData) > 0)foreach ($whereData as $key => $val){
            switch ($key){
                case RechargeActListDTO::_rpaId:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'rpa_id='. intval($val);
                    break;
                case RechargeActListDTO::_name:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'rpa_name LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\'';
                    break;
                case RechargeActListDTO::_status:
                    $whereString    .= (strlen($whereString)>0?' AND ':'').'rpa_status='. intval($val);
                    break;
            }
        }
        $isFail                 = false;
        $sql                    = 'SELECT SQL_CALC_FOUND_ROWS rpa_id, rpa_name, rpa_status, rpa_start_time, rpa_stop_time, rpa_time, pgsp_id_android, pgsp_id_apple, pgsp_id_web, rpa_create_time, rpa_update_time FROM '.$this->DbAuto->getTableNameAll('recharge_promotion_act').$whereString.' ORDER BY rpa_id DESC '.$limitString;
        $list                   = $this->DbAuto->getData($sql, $isFail);
        $totalNum               = $this->DbAuto->getDataInt('SELECT FOUND_ROWS() as num', 'num');
        if($isFail) return null;
        $RechargeActVOList      = [];
        if(CommArray::isForeach($list)){
            $pgspIdAndroidList  = array_map('intval', array_unique(array_filter(array_column($list, 'pgsp_id_android'))));
            $pgspIdAppleList    = array_map('intval', array_unique(array_filter(array_column($list, 'pgsp_id_apple'))));
            $pgspIdWebList      = array_map('intval', array_unique(array_filter(array_column($list, 'pgsp_id_web'))));
            $PayGoodsVOList     = PayCtl::tag()->getPayGoodsBatch(array_merge_recursive($pgspIdAndroidList, $pgspIdAppleList, $pgspIdWebList));
            foreach($list as $info){
                $rpaIdItem              = intval($info['rpa_id']??0);
                if($rpaIdItem < 1) continue;
                $RechargeActVO          = $this->getRechargeActVO($info);
                if(!($RechargeActVO instanceof RechargeActVO)) continue;
                $pgspIdAndroidItem      = intval($info['pgsp_id_android']);
                $pgspIdAppleItem        = intval($info['pgsp_id_apple']);
                $pgspIdWebItem          = intval($info['pgsp_id_web']);
                $PayGoodsVOAndroid      = $PayGoodsVOList[$pgspIdAndroidItem]??null;
                $PayGoodsVOApple        = $PayGoodsVOList[$pgspIdAppleItem]??null;
                $PayGoodsVOWeb          = $PayGoodsVOList[$pgspIdWebItem]??null;
                if($PayGoodsVOAndroid instanceof PayGoodsVO) $RechargeActVO->setGoodsAndroid($PayGoodsVOAndroid);
                if($PayGoodsVOApple instanceof PayGoodsVO) $RechargeActVO->setGoodsApple($PayGoodsVOApple);
                if($PayGoodsVOWeb instanceof PayGoodsVO) $RechargeActVO->setGoodsWeb($PayGoodsVOWeb);
                $RechargeActVOList[]    = $RechargeActVO;
            }
        }
        $RechargeActListVO      = new RechargeActListVO();
        $RechargeActListVO->setList($RechargeActVOList);
        $RechargeActListVO->setPage($Page->getPageVO($totalNum));
        return $RechargeActListVO;
    }

    /**
     * @param array $info
     * @return RechargeActVO|null
     * getRechargeActVO
     */
    public function getRechargeActVO(array $info):?RechargeActVO
    {
        $rpaId              = intval($info['rpa_id']??0);
        if($rpaId < 1) return null;
        $RechargeActVO      = new RechargeActVO();
        $RechargeActVO->setRpaId($rpaId);
        $RechargeActVO->setName(trim($info['rpa_name']));
        $RechargeActVO->setStatus(YesOrNoEnum::parseValue($info['rpa_status']));
        $RechargeActVO->setStartTime(intval($info['rpa_start_time']));
        $RechargeActVO->setStopTime(intval($info['rpa_stop_time']));
        $RechargeActVO->setLimitTime(intval($info['rpa_time']));
        $RechargeActVO->setPgspIdAndroid(intval($info['pgsp_id_android']));
        $RechargeActVO->setPgspIdApple(intval($info['pgsp_id_apple']));
        $RechargeActVO->setPgspIdWeb(intval($info['pgsp_id_web']));
        $RechargeActVO->setCreateTime(intval($info['rpa_create_time']));
        $RechargeActVO->setUpdateTime(intval($info['rpa_update_time']));
        return $RechargeActVO;
    }

    /**
     * @param array $setData
     * @return int
     * rechargeActAdd
     */
    public function rechargeActAdd(array $setData):int
    {
        if(count($setData) < 1) return 0;
        $setString      = '';
        $PayCtl         = PayCtl::tag();
        $haveGoods      = false;
        foreach ($setData as $key => $val){
            switch ($key){
                case RechargeActAddDTO::_name:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'rpa_name=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case RechargeActAddDTO::_status:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'rpa_status='. intval($val);
                    break;
                case RechargeActAddDTO::_startTime:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'rpa_start_time='.intval($val);
                    break;
                case RechargeActAddDTO::_stopTime:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'rpa_stop_time='.intval($val);
                    break;
                case RechargeActAddDTO::_limitTime:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'rpa_time='.intval($val);
                    break;
                case RechargeActAddDTO::_pgspIdAndroid:
                    $pgspId         = intval($val);
                    if($pgspId > 0){
                        $goodsSrc   = $PayCtl->getPayGoodsSrc($pgspId);
                        if(!isset($goodsSrc['pgsp_id'])) return 0;
                        $haveGoods  = true;
                    }else{
                        $pgspId     = 0;
                    }
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_id_android='.$pgspId;
                    break;
                case RechargeActAddDTO::_pgspIdApple:
                    $pgspId         = intval($val);
                    if($pgspId > 0){
                        $goodsSrc   = $PayCtl->getPayGoodsSrc($pgspId);
                        if(!isset($goodsSrc['pgsp_id'])) return 0;
                        $haveGoods  = true;
                    }else{
                        $pgspId     = 0;
                    }
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_id_apple='.$pgspId;
                    break;
                case RechargeActAddDTO::_pgspIdWeb:
                    $pgspId         = intval($val);
                    if($pgspId > 0){
                        $goodsSrc   = $PayCtl->getPayGoodsSrc($pgspId);
                        if(!isset($goodsSrc['pgsp_id'])) return 0;
                        $haveGoods  = true;
                    }else{
                        $pgspId     = 0;
                    }
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_id_web='.$pgspId;
                    break;
            }
        }
        if(strlen($setString) < 1 || !$haveGoods)  return 0;
        $currTime   = CommTime::getTimeStamp(0);
        $isFail     = false;
        $sql        = 'INSERT INTO '.$this->DbAuto->getTableNameAll('recharge_promotion_act').' SET '.$setString.', rpa_delete=0, rpa_create_time='.$currTime.', rpa_update_time='.$currTime;
        $rpaId     = $this->DbAuto->getDataId($sql, $isFail);
        if($isFail || $rpaId < 1) return 0;
        return $rpaId;
    }

    /**
     * @param int $rpaId
     * @param array $setData
     * @return bool
     * rechargeActEdit
     */
    public function rechargeActEdit(int $rpaId, array $setData):bool
    {
        if($rpaId < 1 || count($setData) < 1) return false;
        $setString      = '';
        $PayCtl         = PayCtl::tag();
        $haveGoods      = !(isset($setData[RechargeActEditDTO::_pgspIdAndroid]) || isset($setData[RechargeActEditDTO::_pgspIdApple]) || isset($setData[RechargeActEditDTO::_pgspIdWeb]));
        foreach ($setData as $key => $val){
            switch ($key){
                case RechargeActEditDTO::_name:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'rpa_name=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;
                case RechargeActEditDTO::_status:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'rpa_status='. intval($val);
                    break;
                case RechargeActEditDTO::_startTime:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'rpa_start_time='.intval($val);
                    break;
                case RechargeActEditDTO::_stopTime:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'rpa_stop_time='.intval($val);
                    break;
                case RechargeActEditDTO::_limitTime:
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'rpa_time='.intval($val);
                    break;
                case RechargeActEditDTO::_pgspIdAndroid:
                    $pgspId         = intval($val);
                    if($pgspId > 0){
                        $goodsSrc   = $PayCtl->getPayGoodsSrc($pgspId);
                        if(!isset($goodsSrc['pgsp_id'])) return false;
                        $haveGoods  = true;
                    }else{
                        $pgspId     = 0;
                    }
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_id_android='.$pgspId;
                    break;
                case RechargeActEditDTO::_pgspIdApple:
                    $pgspId         = intval($val);
                    if($pgspId > 0){
                        $goodsSrc   = $PayCtl->getPayGoodsSrc($pgspId);
                        if(!isset($goodsSrc['pgsp_id'])) return false;
                        $haveGoods  = true;
                    }else{
                        $pgspId     = 0;
                    }
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_id_apple='.$pgspId;
                    break;
                case RechargeActEditDTO::_pgspIdWeb:
                    $pgspId         = intval($val);
                    if($pgspId > 0){
                        $goodsSrc   = $PayCtl->getPayGoodsSrc($pgspId);
                        if(!isset($goodsSrc['pgsp_id'])) return false;
                        $haveGoods  = true;
                    }else{
                        $pgspId     = 0;
                    }
                    $setString      .= (strlen($setString) > 0 ? ', ' : '') . 'pgsp_id_web='.$pgspId;
                    break;
            }
        }
        if(strlen($setString) < 1 || !$haveGoods) return false;
        $isFail     = false;
        $currTime   = CommTime::getTimeStamp(0);
        $sql        = 'UPDATE '.$this->DbAuto->getTableNameAll('recharge_promotion_act').' SET '.$setString.', rpa_update_time='.$currTime.' WHERE rpa_id='.$rpaId.' AND rpa_delete=0';
        if($this->DbAuto->getDataNum($sql, $isFail) < 1 || $isFail) return false;
        return true;
    }
}